In multitenant computing environments, multiple client computers run tenant applications in a single instance of a virtual machine, such as the Java Virtual Machine (JVM). For clients executing applications based in the Java® programming language, the single virtual machine instance is the JVM, which executes on a server computer and provides a virtual computing environment that accesses the physical resources of the server computer while maintaining isolation among the tenant applications and information that they access. The JVM executes Java bytecode using threads. Threads contain a program counter and a stack. The program counter keeps track of where the JVM is executing instructions (e.g., the memory location currently being used) and the number of instructions that have been executed on the thread. The stack is a last in first out (LIFO) data structure that contains frames, which include the bytecode detailing instructions to be performed by the server computer physical resources.
During execution of the thread, the thread can be at a “safepoint” or not at a safepoint. When at a safepoint, the thread's representation of the JVM is well described, and can be safely manipulated and seen by other threads in the JVM. When the thread reaches a safepoint, the thread may be safely blocked for a period of time in order to perform actions that affect all threads, such as garbage collection. During compilation of Java bytecode into compiled code, the compiler can determine that a safepoint exists at a certain place in the code and insert additional instructions that instruct the thread executing the compiled code to perform certain functions outside of the compiled application code.